﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once

#include "IElement.h"

namespace gcmp
{
    class IEditModeBehavior;

    /// \brief 编辑模式类
    class GCMP_MODEL_INTERFACE_EXPORT IEditMode : public IElement
    {
        DEFINE_CAST_DERIVED(gcmp::IEditMode, gcmp::IElement)
    public:
        /// \brief 析构函数
        virtual ~IEditMode() {}

        /// \brief 创建编辑模式，内置的编辑模式不用创建，在文档初始化时会自动创建，可以直接Get
        ///
        /// 不能创建相同editModeType的编辑模式
        /// \param pDoc 文档指针
        /// \param opEditModeBehavior 编辑模式可扩展的行为
        /// \return nullptr-创建失败；非nullptr-创建成功
        static IEditMode* Create(IDocument* pDoc, OwnerPtr<IEditModeBehavior> opEditModeBehavior);

        /// \brief 获取编辑模式
        /// \param pDoc 文档指针
        /// \param editModeType 编辑模式类型
        /// \return nullptr-获取失败；非nullptr-获取成功
        static IEditMode* Get(IDocument* pDoc, std::wstring editModeType);

        /// \brief 获取顶层的编辑模式
        ///
        /// 编辑模式可以嵌套，可以从一个编辑模式进入另一个编辑模式，
        /// 如果当前不在编辑模式环境下，则返回空
        /// \param pDoc 编辑模式所在的文档
        /// \return nullptr-获取失败；非nullptr-获取成功
        static IEditMode* GetTopActiveEditMode(const IDocument* pDoc);

    public:
        /// \brief 获取编辑模式可扩展的行为
        /// \return nullptr-获取失败；非nullptr-获取成功
        virtual const IEditModeBehavior *GetEditModeBehavior() const = 0;
        /// \brief 获取编辑模式可扩展的行为
        /// \return nullptr-获取失败；非nullptr-获取成功
        virtual IEditModeBehavior *GetEditModeBehavior() = 0;

        /// \brief 设置辅助对象的行为组件，用于扩展辅助对象的行为
        ///
        /// \param pBehavior 辅助对象的行为组件指针
        /// \param moduleGroupGuid 所在的专业
        /// \return 添加成功：true；添加失败：false
        virtual bool SetEditModeBehavior(OwnerPtr<IEditModeBehavior> pBehavior, const Guid& moduleGroupGuid) = 0;

        /// \brief 获取编辑模式类型
        /// \return 编辑模式类型
        virtual std::wstring GetEditModeType() const = 0;
        /// \brief 判断对象在编辑模式中是否可编辑，不可编辑的物体会灰显，且不能被选中
        /// \param pElement 判断的对象
        /// \return true-可编辑；false-不可编辑
        virtual bool IsElementEditable(const IElement* pElement) const = 0;
        /// \brief 判断编辑对象是否受视图范围影响
        ///
        /// 有些编辑模式下希望一些元素的显示不受视图范围的限制，例如楼板轮廓线的编辑模式，
        /// 希望轮廓线在所有的平面视图都可见，即使不在平面视图的视图范围内
        /// \param pElement 查询的对象
        /// \return true-永远显示对象；false-对象IEditMode
        virtual bool IsNotAffectedByViewRange(const IElement* pElement) const = 0;
    
    public:
        /// \brief 获取编辑模式编辑的对象Id，可以是Invalid，例如拉伸体编辑模式编辑的对象是拉伸体
        /// \return 编辑模式编辑的对象Id
        virtual ElementId GetEditingElementId() const = 0;

        /// \brief 是否作为子编辑模式，例如在位编辑里面进入的编辑模式就是子编辑模式
        /// \return true-是子编辑模式；false-不是是子编辑模式
        // todo gcmp 了解具体含义
        virtual bool GetIsChildEditMode() const = 0;

    public:
        /// \brief 进入编辑模式
        /// \param pDoc 文档指针
        /// \param editingElementId 编辑的对象，可以是Invalid，例如拉伸体编辑模式编辑的对象是拉伸体
        /// \param isCreating 是否是创建过程，比如创建楼板还是编辑楼板
        /// \param isChildEditMode 是否作为子编辑模式
        /// \return true-成功；false-失败
        virtual bool StartEditing(IDocument* pDoc, const ElementId& editingElementId, bool isCreating, bool isChildEditMode) = 0;

        /// \brief 退出编辑模式
        ///
        /// 退出编辑模式的顺序和进入编辑模式的顺序相反，如果退出的不是顶层的编辑模式，返回失败
        /// \param pDoc 文档指针
        /// \return true-成功；false-失败
        virtual bool EndEditing(IDocument* pDoc) = 0;
    public:
        /// \brief 获取Implementation Uid
        ///
        /// \return UniIdentity 返回ImplementationUid
        static UniIdentity GetImplementationUid();

        /// \brief 获取当前的编辑状态
        ///
        /// \return true-当前处于创建状态；false-当前处于编辑状态
        virtual bool GetIsCreating() const = 0;

        /// \brief 设置当前的编辑状态
        ///
        /// \true-当前处于创建状态；false-当前处于编辑状态
        virtual void SetIsCreating(bool isCreating) = 0;
    };
}




